package main

import "fmt"

// defer 推迟延缓
func main() {

	n3 := sum(10, 20)
	fmt.Printf("res:n3=%d\n", n3)
	//step1 n1= 10
	//step2 n2= 20
	//step4 n2= 20
	//defer:step5 res= 30
	//defer:step3 res= 30
	//res:n3=30

	doQuery()
	//openConnect ...
	//doQueryJob ...
	//closeConnect ...

	testSum()

}

func sum(n1 int, n2 int) int {
	//此处会先执行：
	//step1 n1=
	//step2 n2=
	//step4 n2=
	//然后执行defer的语句，defer栈中FILO方式执行，所以defer预计执行顺序：
	//defer:step5 res=
	//defer:step3 res=

	fmt.Println("step1 n1=", n1)
	fmt.Println("step2 n2=", n2)

	res := n1 + n2

	//当执行到defer时，会将defer后面的语句压入独立的栈中，暂时不执行
	//当函数执行完毕后，再从defer栈中FILO方式执行
	defer fmt.Println("defer:step3 res=", res)
	fmt.Println("step4 n2=", n2)

	defer fmt.Println("defer:step5 res=", res)

	return res
}

// defer语句定义时，就会进行值拷贝
func testSum() int {
	var n1, n2 = 10, 20

	//当执行到defer时，会将defer后面的语句压入独立的栈中，暂时不执行
	//当函数执行完毕后，再从defer栈中FILO方式执行
	defer fmt.Println("step1 n1=", n1) // 还是10，会把n1拷贝一份
	defer fmt.Println("step2 n2=", n2) // 还是20，会把n1拷贝一份
	n1++
	n2++
	res := n1 + n2
	defer fmt.Println("step3 res=", res) //32
	return res
}

func doQuery() {
	openConnect()                 //第一执行
	defer closeConnect()          //defer语句，最后从defer栈中FILO执行
	fmt.Println("doQueryJob ...") //第二执行

}
func openConnect() {
	fmt.Println("openConnect ...")
}

func closeConnect() {
	fmt.Println("closeConnect ...")
}
